const winston = require('winston')
const path = require('path')
const fs = require('fs')
const config = require('../config')

// 确保日志目录存在
const logDir = path.dirname(config.logging.file)
if (!fs.existsSync(logDir)) {
  fs.mkdirSync(logDir, { recursive: true })
}

// 自定义日志格式
const logFormat = winston.format.combine(
  winston.format.timestamp({
    format: 'YYYY-MM-DD HH:mm:ss'
  }),
  winston.format.errors({ stack: true }),
  winston.format.json(),
  winston.format.printf(({ timestamp, level, message, stack, ...meta }) => {
    let log = `${timestamp} [${level.toUpperCase()}]: ${message}`
    
    // 添加堆栈信息（如果有错误）
    if (stack) {
      log += `\n${stack}`
    }
    
    // 添加元数据
    if (Object.keys(meta).length > 0) {
      log += `\n${JSON.stringify(meta, null, 2)}`
    }
    
    return log
  })
)

// 控制台格式（开发环境）
const consoleFormat = winston.format.combine(
  winston.format.colorize(),
  winston.format.timestamp({
    format: 'HH:mm:ss'
  }),
  winston.format.printf(({ timestamp, level, message, stack }) => {
    let log = `${timestamp} ${level}: ${message}`
    if (stack) {
      log += `\n${stack}`
    }
    return log
  })
)

// 创建传输器
const transports = [
  // 文件传输器
  new winston.transports.File({
    filename: config.logging.file,
    level: config.logging.level,
    format: logFormat,
    maxsize: 5242880, // 5MB
    maxFiles: 5
  }),
  
  // 错误日志文件
  new winston.transports.File({
    filename: path.join(logDir, 'error.log'),
    level: 'error',
    format: logFormat,
    maxsize: 5242880, // 5MB
    maxFiles: 5
  })
]

// 开发环境添加控制台输出
if (config.server.env === 'development') {
  transports.push(
    new winston.transports.Console({
      level: 'debug',
      format: consoleFormat
    })
  )
}

// 创建日志器
const logger = winston.createLogger({
  level: config.logging.level,
  format: logFormat,
  transports,
  // 处理未捕获的异常
  exceptionHandlers: [
    new winston.transports.File({
      filename: path.join(logDir, 'exceptions.log'),
      format: logFormat
    })
  ],
  // 处理未处理的Promise拒绝
  rejectionHandlers: [
    new winston.transports.File({
      filename: path.join(logDir, 'rejections.log'),
      format: logFormat
    })
  ]
})

// 扩展日志器功能
class Logger {
  constructor(winstonLogger) {
    this.winston = winstonLogger
  }

  // 基础日志方法
  debug(message, meta = {}) {
    this.winston.debug(message, meta)
  }

  info(message, meta = {}) {
    this.winston.info(message, meta)
  }

  warn(message, meta = {}) {
    this.winston.warn(message, meta)
  }

  error(message, error = null, meta = {}) {
    if (error instanceof Error) {
      this.winston.error(message, { ...meta, error: error.message, stack: error.stack })
    } else {
      this.winston.error(message, meta)
    }
  }

  // 业务日志方法
  logRequest(req, res, responseTime) {
    const logData = {
      method: req.method,
      url: req.url,
      userAgent: req.get('User-Agent'),
      ip: req.ip,
      statusCode: res.statusCode,
      responseTime: `${responseTime}ms`,
      userId: req.user?.id || 'anonymous'
    }

    if (res.statusCode >= 400) {
      this.warn('HTTP Request Failed', logData)
    } else {
      this.info('HTTP Request', logData)
    }
  }

  logAuth(action, userId, success, details = {}) {
    const logData = {
      action,
      userId,
      success,
      ...details
    }

    if (success) {
      this.info(`Auth Success: ${action}`, logData)
    } else {
      this.warn(`Auth Failed: ${action}`, logData)
    }
  }

  logAICall(userId, model, success, responseTime, details = {}) {
    const logData = {
      userId,
      model,
      success,
      responseTime: `${responseTime}ms`,
      ...details
    }

    if (success) {
      this.info('AI Call Success', logData)
    } else {
      this.error('AI Call Failed', null, logData)
    }
  }

  logSecurity(event, details = {}) {
    this.warn(`Security Event: ${event}`, details)
  }

  logPerformance(operation, duration, details = {}) {
    const logData = {
      operation,
      duration: `${duration}ms`,
      ...details
    }

    if (duration > 1000) {
      this.warn('Slow Operation', logData)
    } else {
      this.debug('Performance', logData)
    }
  }
}

module.exports = new Logger(logger)